package com.urbanski.util.primitives;

/**
 * This class represents an integer that can be modified without creating a new
 * instance. Its functionality is equivalent to the Integer class in all but
 * that regard. All Integer methods, other than the static methods that do not
 * return Integer, have been replicated. Under the hood, some methods are
 * performed by reusing Integer methods.
 * 
 * @author murbanski004
 * 
 */
public class MutableInteger implements Comparable<MutableInteger>
{
	private int integer;

	/**
	 * Constructs a new MutableInteger with the specified value
	 * 
	 * @param value
	 *            the value of this MutableInteger
	 */
	public MutableInteger(int value)
	{
		integer = value;
	}

	/**
	 * Constructs a new MutableInteger with a value obtained by parsing the
	 * specified String as per Integer.parseInt.
	 * 
	 * @param s
	 *            the String to parse to the value of this MutableInteger
	 */
	public MutableInteger(String s)
	{
		integer = Integer.parseInt(s);
	}

	private MutableInteger(Integer i)
	{
		this(i.intValue());
	}

	/**
	 * Returns the value of this MutableInteger as a byte.
	 * 
	 * @return the value of this MutableInteger as a byte
	 */
	public byte byteValue()
	{
		return (byte) integer;
	}

	/**
	 * Compares this MutableInteger to the specified MutualInteger.
	 * 
	 * @return a negative number if this MutableInteger's value is less than
	 *         anotherInteger's value, 0 if they are equal, or positive is this
	 *         value is greater than anotherInteger's
	 */
	public int compareTo(MutableInteger anotherInteger)
	{
		return integer - anotherInteger.integer;
	}

	/**
	 * Decodes the specified String into a MutableInteger
	 * 
	 * @param nm
	 *            the Strng to decode
	 * @return a MutableInteger representing the decoded String
	 */
	public static MutableInteger decode(String nm)
	{
		return new MutableInteger(Integer.decode(nm));
	}

	/**
	 * Returns the value of this MutableInteger as a double
	 * 
	 * @return the value of this MutableInteger as a double
	 */
	public double doubleValue()
	{
		return (double) integer;
	}

	@Override
	public int hashCode()
	{
		return integer;
	}

	@Override
	public boolean equals(Object obj)
	{
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (!(obj instanceof MutableInteger))
			return false;
		MutableInteger other = (MutableInteger) obj;
		return integer == other.integer;
	}

	/**
	 * Returns the value of this MutableInteger as a float
	 * 
	 * @return the value of this MutableInteger as a float
	 */
	public float floatValue()
	{
		return (float) integer;
	}

	public static MutableInteger getInteger(String nm)
	{
		return new MutableInteger(Integer.getInteger(nm));
	}

	public static MutableInteger getInteger(String nm, int val)
	{
		return new MutableInteger(Integer.getInteger(nm, val));
	}

	public static MutableInteger getInteger(String nm, MutableInteger val)
	{
		return new MutableInteger(Integer.getInteger(nm, val.integer));
	}

	public int intValue()
	{
		return integer;
	}

	public long longValue()
	{
		return integer;
	}

	public short shortValue()
	{
		return (short) integer;
	}

	public String toString()
	{
		return Integer.toString(integer);
	}

	public static MutableInteger valueOf(int i)
	{
		return new MutableInteger(i);
	}

	public static MutableInteger valueOf(String s)
	{
		return new MutableInteger(s);
	}

	public static MutableInteger valueOf(String s, int radix)
	{
		return new MutableInteger(Integer.valueOf(s, radix));
	}

	/**
	 * Sets the value of this MutableInteger
	 * 
	 * @param i
	 *            the value to set
	 */
	public void setValue(int i)
	{
		integer = i;
	}

	/**
	 * Increments the value of this MutableInteger by one and returns itself.
	 * This can be used to chain expressions.
	 * 
	 * @return a reference to this MutableInteger after incrementing the value
	 */
	public MutableInteger increment()
	{
		integer++;
		return this;
	}

	/**
	 * Increments the value of this MutableInteger by the specified amount and
	 * returns itself. This can be used to chain expressions.
	 * 
	 * @return a reference to this MutableInteger after incrementing the value
	 */
	public MutableInteger increment(int amount)
	{
		integer += amount;
		return this;
	}

	/**
	 * Decrements the value of this MutableInteger by one and returns itself.
	 * This can be used to chain expressions.
	 * 
	 * @return a reference to this MutableInteger after decrementing the value
	 */
	public MutableInteger decrement()
	{
		integer--;
		return this;
	}

	/**
	 * Decrements the value of this MutableInteger by the specified amount and
	 * returns itself. This can be used to chain expressions.
	 * 
	 * @return a reference to this MutableInteger after decrementing the value
	 */
	public MutableInteger decrement(int amount)
	{
		integer -= amount;
		return this;
	}

	/**
	 * Negates the value of this MutableInteger and returns itself. This can be
	 * used to chain expressions.
	 * 
	 * @return a reference to this MutableInteger after negating its value.
	 */
	public MutableInteger negate()
	{
		integer = -integer;
		return this;
	}
}
